﻿//-----------------------------------------------------------------------
// <copyright>
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
// </copyright>
//----------------------------------------------------------------------- 
using System;
using System.Linq;
using System.Xml;
using Fulcrum.ControlGenerator;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Fulcrum.UnitTests.ControlGenerator
{
    [TestClass]
    public class BaseDependecyPropertyXmlConfigurationTests
    {
        public BaseDependecyPropertyXmlConfigurationTests()
        {
            // nothing
        }

        const string StandardXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' isReadOnly='true' coerceValue='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";

        const string CoerceValueTrueXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' isReadOnly='true' coerceValue='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";
        const string CoerceValueFalseXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' isReadOnly='true' coerceValue='false' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";
        const string CoerceValueMissingXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' isReadOnly='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";
        
        const string IsReadOnlyTrueXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' isReadOnly='true' coerceValue='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";
        const string IsReadOnlyFalseXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' isReadOnly='false' coerceValue='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";
        const string IsReadOnlyMissingXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' coerceValue='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";
        
        const string ValidateValueTrueXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";
        const string ValidateValueFalseXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' validateValue='false' visibility='Public' metadataOptions='one | two'></blah>";
        const string ValidateValueMissingXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' visibility='Public' metadataOptions='one | two'></blah>";
        
        const string DefaultValueEmptyXml = "<blah name='my name' type='MyType' defaultValue='' isReadOnly='true' coerceValue='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";
        const string DefaultValueMissingXml = "<blah name='my name' type='MyType' isReadOnly='true' coerceValue='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";

        const string EmptyMetadataOptionsXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' metadataOptions=''></blah>";
        const string SingleMetadataOptionsXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' metadataOptions='single'></blah>";
        const string ManyMetadataOptionsXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' metadataOptions='one | two'></blah>";
        const string MissingMetadataOptionsXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' ></blah>";

        const string EmptyNameXml = "<blah name='' type='MyType' defaultValue='defaultValue' isReadOnly='true' coerceValue='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";
        const string MissingNameXml = "<blah type='MyType' defaultValue='defaultValue' isReadOnly='true' coerceValue='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";

        const string EmptyTypeXml = "<blah name='my name' type='' defaultValue='defaultValue' isReadOnly='true' coerceValue='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";
        const string MissingTypeXml = "<blah name='my name' defaultValue='defaultValue' isReadOnly='true' coerceValue='true' validateValue='true' visibility='Public' metadataOptions='one | two'></blah>";
        
        const string PublicVisibilityXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' visibility='Public' metadataOptions='one | two'></blah>";
        const string PrivateVisibilityXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' visibility='Private' metadataOptions='one | two'></blah>";
        const string InvalidVisibilityXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' visibility='Junk' metadataOptions='one | two'></blah>";
        const string MissingVisibilityXml = "<blah name='my name' type='MyType' defaultValue='defaultValue' metadataOptions='one | two'></blah>";

        [TestMethod]
        public void TestReaderAdvancement()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(StandardXml);

            Assert.IsTrue(xmlReader.IsStartElement());

            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsTrue(xmlReader.IsStartElement());
        }

        [TestMethod]
        public void TestCoerceValueTrue()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(CoerceValueTrueXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsTrue(config.CoerceValue);
        }

        [TestMethod]
        public void TestCoerceValueFalse()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(CoerceValueFalseXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsFalse(config.CoerceValue);
        }

        [TestMethod]
        public void TestCoerceValueMissing()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(CoerceValueMissingXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsFalse(config.CoerceValue);
        }

        [TestMethod]
        public void TestIsReadOnlyTrue()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(IsReadOnlyTrueXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsTrue(config.IsReadOnly);
        }

        [TestMethod]
        public void TestIsReadOnlyFalse()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(IsReadOnlyFalseXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsFalse(config.IsReadOnly);
        }

        [TestMethod]
        public void TestIsReadOnlyMissing()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(IsReadOnlyMissingXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsFalse(config.IsReadOnly);
        }

        [TestMethod]
        public void TestValidateValueTrue()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(ValidateValueTrueXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsTrue(config.ValidateValue);
        }

        [TestMethod]
        public void TestValidateValueFalse()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(ValidateValueFalseXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsFalse(config.ValidateValue);
        }

        [TestMethod]
        public void TestValidateValueMissing()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(ValidateValueMissingXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsFalse(config.ValidateValue);
        }

        [TestMethod]
        public void TestDefaultValue()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(StandardXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual("defaultValue", config.DefaultValue);
        }

        [TestMethod]
        public void TestDefaultValueEmpy()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(DefaultValueEmptyXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual("", config.DefaultValue);
        }

        [TestMethod]
        public void TestDefaultValueMissing()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(DefaultValueMissingXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsNull(config.DefaultValue);
        }

        [TestMethod]
        public void TestDefaultMetadataOptionsEmpty()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(EmptyMetadataOptionsXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual(0, config.MetadataOptions.Count);
        }

        [TestMethod]
        public void TestDefaultMetadataOptionsOne()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(SingleMetadataOptionsXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual(1, config.MetadataOptions.Count);
            Assert.AreEqual("single", config.MetadataOptions.ElementAt(0));
        }

        [TestMethod]
        public void TestDefaultMetadataOptionsMany()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(ManyMetadataOptionsXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual(2, config.MetadataOptions.Count);
            Assert.AreEqual(" two", config.MetadataOptions.ElementAt(0));
            Assert.AreEqual("one ", config.MetadataOptions.ElementAt(1));
        }

        [TestMethod]
        public void TestDefaultMetadataOptionsMissing()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(MissingMetadataOptionsXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual(0, config.MetadataOptions.Count);
        }

        [TestMethod]
        public void TestName()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(StandardXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual("my name", config.Name);
        }

        [TestMethod]
        public void TestNameEmpty()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(EmptyNameXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual("", config.Name);
        }

        [TestMethod]
        public void TestNameMissing()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(MissingNameXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsNull(config.Name);
        }

        [TestMethod]
        public void TestType()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(StandardXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual("MyType", config.Type);
        }

        [TestMethod]
        public void TestTypeEmpty()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(EmptyTypeXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual("", config.Type);
        }

        [TestMethod]
        public void TestTypeMissing()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(MissingTypeXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.IsNull(config.Type);
        }

        [TestMethod]
        public void TestVisibilityPublic()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(PublicVisibilityXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual(PropertyVisibility.Public, config.Visibility);
        }

        [TestMethod]
        public void TestVisibilityPrivate()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(PrivateVisibilityXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual(PropertyVisibility.Private, config.Visibility);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void TestVisibilityInvalid()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(InvalidVisibilityXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);
        }

        [TestMethod]
        public void TestVisibilityMissing()
        {
            var xmlReader = XmlTestHelp.CreateXmlReader(MissingVisibilityXml);
            var config = new BaseDependencyPropertyXmlConfigurationTestDouble(xmlReader);

            Assert.AreEqual(PropertyVisibility.Public, config.Visibility);
        }

        class BaseDependencyPropertyXmlConfigurationTestDouble : BaseDependencyPropertyXmlConfiguration
        {
            public BaseDependencyPropertyXmlConfigurationTestDouble(XmlReader xmlReader)
                : base(xmlReader)
            {
                // nothing
            }
        }
    }
}
